import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime  # 数据索引改为时间
import numpy as np
import statsmodels.api as sm  # acf,pacf图
from statsmodels.tsa.stattools import adfuller  # adf检验
from pandas.plotting import autocorrelation_plot
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_squared_error
from matplotlib import pyplot
from tqdm import tqdm

dayPriceList = []


# 归一化
def normalization():
    minVal = dayPriceList["Value"].min(0)
    maxVal = dayPriceList["Value"].max(0)
    ranges = maxVal - minVal
    m = dayPriceList.shape[0]
    # print(minVal, maxVal, ranges)
    # print(m)
    dayPriceList["Value"] = dayPriceList["Value"] - np.tile(minVal, m)
    dayPriceList["Value"] = dayPriceList["Value"] / np.tile(ranges, m)
    # print(dayPriceList["Value"])
    # plt.figure(figsize=(10, 6))
    # dayPriceList.plot()
    # plt.show()
    return 0


if __name__ == '__main__':
    # import data
    filename = 'gold'
    dayPriceList = pd.read_excel("data/"+filename+".xlsx")
    print(dayPriceList.head)
    dayPriceList = pd.DataFrame(dayPriceList, dtype=np.float64)

    # 归一化
    # normalization()

    # 时序图
    plt.figure(figsize=(10, 6))
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
    dayPriceList["Value"].plot(title="Price")
    plt.xlabel('Recording ID', fontsize=10, verticalalignment='top')
    plt.ylabel('Daily Price', fontsize=10, horizontalalignment='center')
    # plt.show()
    # plt.savefig('save/'+filename+'/data.png', bbox_inches='tight')

    # acf,pacf图
    fig = plt.figure(figsize=(12, 8))
    ax1 = fig.add_subplot(211)
    fig = sm.graphics.tsa.plot_acf(dayPriceList, lags=20, ax=ax1)
    ax2 = fig.add_subplot(212)
    fig = sm.graphics.tsa.plot_pacf(dayPriceList, lags=20, ax=ax2)
    # plt.show()
    # plt.savefig('save/' + filename + '/acf_pcf.png', bbox_inches='tight')

    # 进行ADF检验
    temp = np.array(dayPriceList["Value"])
    t = adfuller(temp)  # ADF检验
    output = pd.DataFrame(
        index=['Test Statistic Value', "p-value", "Lags Used", "Number of Observations Used", "Critical Value(1%)",
               "Critical Value(5%)", "Critical Value(10%)"], columns=['value'])
    output['value']['Test Statistic Value'] = t[0]
    output['value']['p-value'] = t[1]
    output['value']['Lags Used'] = t[2]
    output['value']['Number of Observations Used'] = t[3]
    output['value']['Critical Value(1%)'] = t[4]['1%']
    output['value']['Critical Value(5%)'] = t[4]['5%']
    output['value']['Critical Value(10%)'] = t[4]['10%']
    print(output)
    output.to_excel('save/'+filename+'/adf.xlsx')

    # p值0.998,即可以认为非平稳
    # ADF检验的原假设是存在单位根，只要这个统计值是小于1%水平下的数字就可以极显著的拒绝原假设，认为数据平稳
    # https://www.lizenghai.com/archives/595.html

    # 差分
    dayPriceList_dx_1 = dayPriceList["Value"].diff(1)
    plt.figure(figsize=(10, 6))
    dayPriceList_dx_1.plot(title="Price_diff")
    plt.xlabel('Recording ID', fontsize=12, verticalalignment='top')
    plt.ylabel('Daily Price_dx', fontsize=14, horizontalalignment='center')
    # plt.show()
    plt.savefig('save/' + filename + '/dfList.png', bbox_inches='tight')

    # 差分序列的ADF平稳性检验
    temp = np.diff(dayPriceList["Value"])
    t = adfuller(temp)  # ADF检验
    output = pd.DataFrame(
        index=['Test Statistic Value', "p-value", "Lags Used", "Number of Observations Used", "Critical Value(1%)",
               "Critical Value(5%)", "Critical Value(10%)"], columns=['value'])
    output['value']['Test Statistic Value'] = t[0]
    output['value']['p-value'] = t[1]
    output['value']['Lags Used'] = t[2]
    output['value']['Number of Observations Used'] = t[3]
    output['value']['Critical Value(1%)'] = t[4]['1%']
    output['value']['Critical Value(5%)'] = t[4]['5%']
    output['value']['Critical Value(10%)'] = t[4]['10%']
    print(output)
    # output.to_excel('save/' + filename + '/df_adf.xlsx')

    # 将差分序列改为与原始数据相同的数据格式
    prices = list(np.diff(dayPriceList["Value"]))
    data2 = {
        "Date": dayPriceList.index[1:],  # 第一天是空值，从第二天开始取
        "Value": prices
    }
    df = pd.DataFrame(data2)
    df['Date'] = pd.to_datetime(df['Date'])
    # df[''date]数据类型为“object”，通过pd.to_datetime将该列数据转换为时间类型，即datetime。
    data_diff = df.set_index(['Date'], drop=True)
    # 将日期设置为索引
    print(data_diff)

    # 差分序列的acf,pacf
    fig = plt.figure(figsize=(12, 8))
    ax1 = fig.add_subplot(211)
    fig = sm.graphics.tsa.plot_acf(data_diff, lags=20, ax=ax1)
    ax2 = fig.add_subplot(212)
    fig = sm.graphics.tsa.plot_pacf(data_diff, lags=20, ax=ax2)
    # plt.savefig('save/' + filename + '/df_acf_pcf.png', bbox_inches='tight')
    plt.show()

    # # 二阶差分
    # dayPriceList_dx_2 = data_diff["Value"].diff(1)
    # plt.figure(figsize=(10, 6))
    # dayPriceList_dx_2.plot(title="Price_diff2")
    # plt.xlabel('Date', fontsize=12, verticalalignment='top')
    # plt.ylabel('Bitcoin Daily Price_dx_2', fontsize=14, horizontalalignment='center')
    # plt.show()
    #
    # # 二阶差分序列的ADF平稳性检验
    # temp = np.diff(data_diff["Value"])
    # t = adfuller(temp)  # ADF检验
    # output = pd.DataFrame(
    #     index=['Test Statistic Value', "p-value", "Lags Used", "Number of Observations Used", "Critical Value(1%)",
    #            "Critical Value(5%)", "Critical Value(10%)"], columns=['value'])
    # output['value']['Test Statistic Value'] = t[0]
    # output['value']['p-value'] = t[1]
    # output['value']['Lags Used'] = t[2]
    # output['value']['Number of Observations Used'] = t[3]
    # output['value']['Critical Value(1%)'] = t[4]['1%']
    # output['value']['Critical Value(5%)'] = t[4]['5%']
    # output['value']['Critical Value(10%)'] = t[4]['10%']
    # print(output)
    #
    # # 将二阶差分序列改为与原始数据相同的数据格式
    # prices = list(np.diff(data_diff["Value"]))
    # data2 = {
    #     "Date": data_diff.index[1:],  # 第一天是空值，从第二天开始取
    #     "Value": prices
    # }
    # df = pd.DataFrame(data2)
    # df['Date'] = pd.to_datetime(df['Date'])
    # # df[''date]数据类型为“object”，通过pd.to_datetime将该列数据转换为时间类型，即datetime。
    # data_diff2 = df.set_index(['Date'], drop=True)
    # # 将日期设置为索引
    # print(data_diff2)

    # # 差分序列的acf,pacf
    # fig = plt.figure(figsize=(12, 8))
    # ax1 = fig.add_subplot(211)
    # fig = sm.graphics.tsa.plot_acf(data_diff2, lags=20, ax=ax1)
    # ax2 = fig.add_subplot(212)
    # fig = sm.graphics.tsa.plot_pacf(data_diff2, lags=20, ax=ax2)
    # plt.show()
